﻿using System.Threading.Tasks;
using Windows.ApplicationModel.AppService;
using Windows.Foundation.Collections;
using Log = Xiaowei.Diagnostics.Debug;
using Debug = Xiaowei.Diagnostics.Debug;
using HP.UtilsLib;
using System.Threading;
using Windows.Storage.Streams;
using Windows.Storage;
using System;
using HP.UtilsLib.Algorithms;
using System.Diagnostics;
using Xiaowei.Settings;
using Xiaowei.Models;

namespace Xiaowei.Services
{
    /// <summary>
    /// A implement of TTSPlayer
    /// </summary>
    public class TTSPlayerService
    {
        static TTSPlayerService instance;
        public static TTSPlayerService Instance { get { return instance = instance ?? new TTSPlayerService(); } }
        public event Action<bool> IsPlayingChanged;

        public bool SaveTTSEnabled { get; set; } = false;

        public bool IsPlaying
        {
            get
            {
                return isPlaying;
            }
            private set
            {
                if (isPlaying != value)
                {
                    isPlaying = value;
                    IsPlayingChanged?.Invoke(value);
                }
            }
        }

        private bool isPlaying = false;

        private ITTSPlayer player = null;
        private ITTSPlayer naudio = new TTSPlayerWithNAudio();
        private ITTSPlayer audiograph = new TTSPlayerWithAudioGraph();
        private ITTSPlayer media = new TTSPlayerWithMediaPlayer();
        public TTSPlayerService()
        {
            player = naudio;
            player.IsPlayingChanged += Player_IsPlayingChanged;

            player = audiograph;
            player.IsPlayingChanged += Player_IsPlayingChanged;

            player = media;
            player.IsPlayingChanged += Player_IsPlayingChanged;
        }

        private void Player_IsPlayingChanged(bool state)
        {
            IsPlaying = state;
        }

        /// <summary>
        /// Cancel the tts which is playing.
        /// The function will return after cancel end.
        /// </summary>
        public void Cancel()
        {
            lock (locker)
            {
                Debug.WriteLine($"TTSPlayerService.Cancel");
                if (IsPlaying)
                {
                    Debug.WriteLine("Pause:Wait for the stopping");
                    player.Cancel();
                }
                Debug.WriteLine($"TTSPlayerService.Cancel end");
            }

        }


        public bool Play(string url)
        {
            if(string.IsNullOrEmpty(url))
            {
                Debug.WriteLine($"TTSPlayerService.PlayTTS: url is null");
                return false;
            }
            Debug.WriteLine($"TTSPlayerService.PlayTTS:{url}");
            lock (locker)
            {
                if (IsPlaying)
                {
                    Debug.WriteLine("Wait for the previous tts stopping");
                    player.Cancel();
                    Debug.WriteLine("Wait for the previous tts stopping end");
                }
                else
                {
                    Debug.WriteLine("Play tts without waiting");
                }
                ChoosePlayer(url);
                bool ret = player.Play(url);
                return ret;
            }
        }

        private readonly object locker = new object();

        private void ChoosePlayer(string url)
        {
            player = naudio;
            //if(url.Contains("ms-appx:///"))
            //{
            //    if(!SystemState.IsLocked && ApplicationModel.Instance.IsBackgroundMode)
            //    {
            //        player = naudio;
            //        Debug.WriteLine("Play local tts with naudio");
            //    }
            //    else
            //    {
            //        player = media;
            //        Debug.WriteLine("Play local tts");
            //    }
            //   
            //   
            //}
            //else
            //{
            //    
            //    if (AppState.wakeFromSleep)
            //    {
            //        player = audiograph;
            //        Debug.WriteLine("Play url tts with audiograph under sleep");
            //    }
            //    else 
            //    {
            //        player = naudio;
            //        Debug.WriteLine("Play url tts with naudio on desktop");
            //    }
            //    
            //
            //}
        }

        private void SaveTTS(string url, string md5)
        {
            if (string.IsNullOrEmpty(url)) return;
#if false
            if (!url.EndsWith(".mp3")) return;
            try
            {
                Debug.WriteLine($"SaveTTS :{md5}");
                Stopwatch sw = new Stopwatch();
                sw.Start();
                var uri = new Uri(url);
                RandomAccessStreamReference reference = RandomAccessStreamReference.CreateFromUri(uri);
                var oper = StorageFile.CreateStreamedFileFromUriAsync(".mp3", uri, reference);
                oper.Completed = async (infor, s) =>
                {
                    var file = infor.GetResults();
                    sw.Stop();

                    var folder = ApplicationData.Current.LocalFolder;
                    var ttsFolder = await folder.CreateFolderAsync("tts", CreationCollisionOption.OpenIfExists);
                    await file.CopyAsync(ttsFolder, $"{md5}-{sw.ElapsedMilliseconds}ms.mp3");

                    Debug.WriteLine($"Save tts file:{md5}-{sw.ElapsedMilliseconds}ms.mp3, IsAvailable:{file.IsAvailable}, " +
                        $"FileType:{file.FileType}, ContentType:{file.ContentType}, Attributes:{file.Attributes}");
                };
                Debug.WriteLine($"SaveTTS End:{md5}");
            } catch (Exception ex)
            {
                Debug.WriteLine($"SaveTTS, ex:{ex}");
            }
#endif
        }


    }
}
